package com.tyx.chargingpile.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.tyx.chargingpile.Enum.ServiceExceptionEume;
import com.tyx.chargingpile.Enum.ServiceMessageEume;
import com.tyx.chargingpile.service.ChargingPileService;
import com.tyx.chargingpile.service.HttpAPIService;
import com.tyx.chargingpile.service.MessageService;
import com.tyx.chargingpile.service.exception.ServiceExcep;
import com.tyx.chargingpile.util.Util;
import com.tyx.chargingpile.vo.HttpResult;
import com.tyx.chargingpile.vo.SocketResponseResult;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import org.apache.http.util.TextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 线下充电上报选择模式
 */
@Service("chargingPileChargeReportChooseModel")
public class ChargingPileChargeReportChooseModel implements ChargingPileService {

    @Value("${chargingback.url}")
    private String url;
    @Autowired
    HttpAPIService httpAPIService;
    private final static Logger LOGGER = LoggerFactory.getLogger(ChargingPileChargeReportChooseModel.class);

    @Override
    public SocketResponseResult execute(ChannelHandlerContext channelHandlerContext, byte[] context) throws Exception {
        String commandId = MessageService.getCommandControl(context);
        String channelId = channelHandlerContext.channel().id().toString();
        Map<String,String> map = MessageService.analysisMessage(context, ServiceMessageEume.CHARGEREPORTCHOOSEMODE.getUpLinePath());
        checkData(map);
        // 取出数据，并且转变
        String pileNum = map.get("pileNum");
        pileNum = pileNum.substring(1,pileNum.length());
        String gunpointNum = Integer.parseInt(map.get("gunpointNum")) + "";
        String powerType = map.get("powerType");
        String cardNo = map.get("cardNo");
        String balacnce = map.get("balacnce");
        balacnce = Double.parseDouble(balacnce) / 100 + "";
        String chargeModel = map.get("chargeModel");
        String chargeModelParam = map.get("chargeModelParam");
        byte[] bChargeModelParam = Util.String2BCD(chargeModelParam);
        int iChargeModelParam = Util.HexToint(bChargeModelParam,bChargeModelParam.length);
        chargeModelParam = iChargeModelParam / 100 + "";
        String orderNum = map.get("orderNum");
        // 推送给后台
        sendMsg(pileNum,gunpointNum,cardNo,balacnce,chargeModel,chargeModelParam,orderNum,channelId,commandId);
        // 下发数据给桩
        Map<String,String> dwn = new HashMap<>();
        dwn.put("gunpointNum",map.get("gunpointNum"));
        dwn.put("powerType",map.get("powerType"));
        dwn.put("pileNum", map.get("pileNum"));
        dwn.put("orderNum", map.get("orderNum"));
        dwn.put("commandBack","FF");
        byte[] dwnContext = MessageService.getMessage(dwn,ServiceMessageEume.CHARGEREPORTCHOOSEMODE.getDwnLinePath());
        ByteBuf pingMessage = Unpooled.buffer();
        pingMessage.writeBytes(dwnContext);
        channelHandlerContext.writeAndFlush(pingMessage);
        LOGGER.info("客户端"+channelId+",指令控制编号："+commandId+",桩编号:" + pileNum + ",线下充电上报选择模式下行报文" + Util.BCD2String(dwnContext));
        return new SocketResponseResult(channelHandlerContext,dwnContext);
    }

    @Override
    public SocketResponseResult execute(ChannelHandlerContext channelHandlerContext, Map data) throws Exception {
        return null;
    }
    /**
     * 报文业务校验
     * @param map
     * @throws ServiceExcep
     */
    private void checkData(Map<String,String> map) throws ServiceExcep {
        if(map == null){
            throw new ServiceExcep(ServiceExceptionEume.MESSAGEPARSINGERROR);
        }
        String pileNum = map.get("pileNum");
        String gunpointNum = map.get("gunpointNum");
        String powerType = map.get("powerType");
        String cardNo = map.get("cardNo");
        String balacnce = map.get("balacnce");
        String chargeModel = map.get("chargeModel");
        String chargeModelParam = map.get("chargeModelParam");
        String orderNum = map.get("orderNum");
        if (TextUtils.isEmpty(pileNum) || TextUtils.isEmpty(gunpointNum) ||TextUtils.isEmpty(powerType) ||TextUtils.isEmpty(cardNo) ||TextUtils.isEmpty(balacnce) ||TextUtils.isEmpty(chargeModel)||TextUtils.isEmpty(chargeModelParam)||TextUtils.isEmpty(orderNum)){
            throw new ServiceExcep(ServiceExceptionEume.INCOMPLETEPARAMETERS);
        }
    }

    /**
     * 调用后台
     * @param pileNum
     * @param gunpointNum
     * @param cardNo
     * @param balacnce
     * @param chargeModel
     * @param chargeModelParam
     * @param orderNum
     */
    @Async
    public void sendMsg(String pileNum ,String gunpointNum,String cardNo ,String balacnce ,String chargeModel,String chargeModelParam ,String orderNum,String channelId,String commandId){
        try {
            JSONObject requestJson = new JSONObject();
            JSONObject dataJson = new JSONObject();
            dataJson.put("DeviceId",pileNum);
            dataJson.put("ChargePortIndex",gunpointNum);
            dataJson.put("CardId",cardNo);
            dataJson.put("AmountMoney",balacnce);
            dataJson.put("ChargeMode",chargeModel);
            dataJson.put("ChargeValue",chargeModelParam);
            dataJson.put("OrderId",orderNum);
            requestJson.put("MainCMD",68);
            requestJson.put("SubCMD",8);
            requestJson.put("Data",dataJson);
            LOGGER.info("客户端"+channelId+",指令控制编号："+commandId+",桩编号:" + pileNum + ",线下充电上报选择模式推送后台" + requestJson.toJSONString());
            HttpResult result = httpAPIService.doPost2Json(url,requestJson.toJSONString());
            if(result.getCode() != 200){
                LOGGER.info("客户端"+channelId+",指令控制编号："+commandId+",桩编号:" + pileNum + ",线下充电上报选择模式推送后台：false");
            }
            LOGGER.info("客户端"+channelId+",指令控制编号："+commandId+",桩编号:" + pileNum + ",线下充电上报选择模式推送后台：true");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}
